#include "SocketClient.h"
#include "format.h"
static SocketClient* _SocketClient = nullptr;
static std::mutex PlayerSocketLocker;
SocketClient::SocketClient(void) : onRecv(nullptr), _socektClient(0)
{
	connectServer("127.0.0.1", 6000);
	_SocketClient = this;
}

SocketClient::~SocketClient(void)
{
	if (_socektClient != 0)
	{
		_mutex.lock();
		this->closeConnect(_socektClient);
		_mutex.unlock();
	}
}
SocketClient* SocketClient::GetInstance()
{
	if (_SocketClient == nullptr)
	{
		ThreadLocker Locker(PlayerSocketLocker);
		if (_SocketClient == nullptr)
		{
			_SocketClient = new SocketClient();
		}
	}
	return _SocketClient;
}
bool SocketClient::initClient()
{
	if (_socektClient != 0)
	{
		_mutex.lock();
		this->closeConnect(_socektClient);
		_mutex.unlock();
	}
	_socektClient = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
	if (error(_socketServer))
	{
		log("init client error!");
		_socektClient = 0;
		return false;
	}
	return true;
}

bool SocketClient::connectServer(const char* serverIP, unsigned short port)
{
	if (!initClient())
	{
		return false;
	}
	struct sockaddr_in serverAddr;
	memset(&serverAddr, 0, sizeof(struct sockaddr_in));
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_port = htons(port);
	serverAddr.sin_addr.s_addr = inet_addr(serverIP);
	int ret = 0;
	ret = connect(_socektClient, (struct sockaddr*)&serverAddr, sizeof(struct sockaddr));
	if (ret < 0)
	{
		this->closeConnect(_socektClient);
		_socektClient = 0;
		return false;
	}
	std::thread recvThread(&SocketClient::recvMessage, this);
	recvThread.detach();
	return true;
}

void SocketClient::recvMessage()
{
	char recvBuf[1024];
	int ret = 0;
	while (true)
	{
		ret = recv(_socektClient, recvBuf, sizeof(recvBuf), 0);
		if (ret < 0)
		{
			log("recv error");
			break;
		}
		log("%s", recvBuf);
		std::string recv = recvBuf;
		MessageComming(recv);
		if (ret > 0 && onRecv != nullptr)
		{
			onRecv(recvBuf, ret);
		}
	}
	_mutex.lock();
	this->closeConnect(_socektClient);
	if (onDisconnect != nullptr)
	{
		onDisconnect();
	}
	_socektClient = 0;
	_mutex.unlock();
}

void SocketClient::MessageComming(std::string args)
{
	sOpcodeMgr->MessageComming(args);
}

void SocketClient::sendMessage(const char* data, int count)
{
	if (!count)
		count = sizeof(data);

	if (_socektClient != 0)
	{
		int ret = send(_socektClient, data, count, 0);
		if (ret < 0)
		{
			log("send error!");
		}
	}
}